package com.csc.data;

import org.apache.jcs.JCS;

import com.csc.dao.BookDAO;
import com.csc.dao.DAOFactory;

public class BookObjManager {
	private static BookObjManager instance = null;
    private static JCS bookCache;
    private DAOFactory odbcDAOFactory;
    private BookDAO bookDao;

    public BookObjManager()
    {
    	odbcDAOFactory = DAOFactory.getDAOFactory(DAOFactory.ODBC);
    	bookDao = odbcDAOFactory.createBookDao();
    	
        try
        {
//        	CompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance(); 
//        	Properties props = new Properties();
//        	props.load(new FileInputStream("cache.ccf"));
//        	ccm.configure(props);


            bookCache = JCS.getInstance("bookCache");
        }
        catch (Exception e)
        {
            // Handle cache region initialization failure
        	e.printStackTrace();
        }

        // Do other initialization that may be necessary, such as getting
        // references to any data access classes we may need to populate
        // value objects later
    }
    
    /**
     * Singleton access point to the manager.
     */
    public static BookObjManager getInstance()
    {
        if (instance == null)
        {
            instance = new BookObjManager();
        }
        return instance;
    }
    /**
     * Retrieves a BookObj.  Default to look in the cache.
     */
    public BookObj getBookObj(int id)
    {
        return getBookObj(id, true);
    }

    /**
     * Retrieves a BookObj. Second argument decides whether to look
     * in the cache. Returns a new value object if one can't be
     * loaded from the database. Database cache synchronization is
     * handled by removing cache elements upon modification.
     */
    public BookObj getBookObj(int id, boolean fromCache)
    {
        BookObj obj = null;

        // First, if requested, attempt to load from cache

        if (fromCache)
        {
        	obj = (BookObj) bookCache.get("BookObj" + id);
        }

        // Either fromCache was false or the object was not found, so
        // call loadBookObj to create it

        if (obj == null)
        {
        	obj = loadBookObj(id);
        }

        return  obj;
    }

    /**
     * Creates a BookObj based on the id of the BOOK table.  Data
     * access could be direct JDBC, some or mapping tool, or an EJB.
     */
    public BookObj loadBookObj(int id)
    {
        BookObj obj = new BookObj();

        obj.setBookId(id);

        try
        {
            boolean found = false;

            // load the data and set the rest of the fields
            // set found to true if it was found
            BookObj bookObj = bookDao.findBook(id);
            if(bookObj != null){
            	obj.setAuthor(bookObj.getAuthor());
            	obj.setBookId(bookObj.getBookId());
            	obj.setIsbn(bookObj.getIsbn());
            	obj.setPrice(bookObj.getPrice());
            	obj.setTitle(bookObj.getTitle());
            	found = true;
            }
            // cache the value object if found

            if (found)
            {
                // could use the defaults like this
                // bookCache.put( "BookVObj" + id, obj );
                // or specify special characteristics

                // put to cache

                bookCache.put("BookObj" + id, obj);
            }

        }
        catch (Exception e)
        {
            // Handle failure putting object to cache
        	e.printStackTrace();
        }

        return obj;
    }
    
    /**
     * update BookObj's in database.  Clears old items and caches
     * new.
     * return: true if success, false if fail
     */
    public boolean updateBookObj(BookObj bookObj)
    {
    	// update BookObj in database
    	if(bookDao.updateBook(bookObj)){
	        try
	        {
	            // since any cached data is no longer valid, we should
	            // remove the item from the cache if it an update.
	
	            if (bookObj.getBookId() != 0)
	            {
	                bookCache.remove("BookVObj" + bookObj.getBookId());
	            }
	
	            // put the new object in the cache
	
	            bookCache.put("BookVObj" + bookObj.getBookId(), bookObj);
	        }
	        catch (Exception e)
	        {
	            // Handle failure removing object or putting object to cache.
	        	e.printStackTrace();
	        }
	        return true;
    	}
        return false;
    }
    
//    /**
//     * put book Obj to cache
//     */
//    public int putBookObj(BookObj bookObj){
//    	try {
//    		bookCache.put("BookObj" + bookObj.getBookId(), bookObj);
//		} catch (Exception e) {
//			// TODO: handle exception
//		}
//    	
//    	return -1;
//    }
//    /**
//     * load book Obj from DB to cache
//     */
//    private void loadBookToCache(){
//    	ArrayList<BookObj> arr = new ArrayList<BookObj>();
//    	arr = bookDao.selectBooks();
//    	for(int i = 0; i < arr.size(); i++){
//    		putBookObj(arr.get(i));
//    	}
//    }
}
